/* Copyright 2025 The OpenXLA Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <gtest/gtest.h>
#include "xla/stream_executor/platform_manager.h"
#include "xla/stream_executor/stream_executor.h"
#include "xla/tsl/platform/status_matchers.h"

namespace stream_executor::gpu {
namespace {
using tsl::testing::IsOkAndHolds;

TEST(SyclKernelTest, CheckKernelLoading) {
  TF_ASSERT_OK_AND_ASSIGN(Platform * platform,
                          PlatformManager::PlatformWithName("SYCL"));
  TF_ASSERT_OK_AND_ASSIGN(StreamExecutor * executor,
                          platform->ExecutorForDevice(0));

  // TODO(intel-tf): This is a temporary workaround to get the test working.
  // This will be replaced with hlo-based spv binary generation once MLIR
  // changes are in place.
  const unsigned char kAddSpv[] = {
      0x03, 0x02, 0x23, 0x07, 0x00, 0x04, 0x01, 0x00, 0x15, 0x00, 0x2B, 0x00,
      0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
      0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00,
      0x11, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
      0x05, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x4F, 0x70, 0x65, 0x6E, 0x43, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x00, 0x00,
      0x0E, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x0F, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
      0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5F, 0x61, 0x64, 0x64, 0x00,
      0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
      0x10, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
      0x04, 0x00, 0x00, 0x00, 0xA0, 0x86, 0x01, 0x00, 0x05, 0x00, 0x05, 0x00,
      0x10, 0x00, 0x00, 0x00, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5F,
      0x61, 0x64, 0x64, 0x00, 0x05, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x00, 0x00,
      0x5F, 0x5F, 0x73, 0x70, 0x69, 0x72, 0x76, 0x5F, 0x42, 0x75, 0x69, 0x6C,
      0x74, 0x49, 0x6E, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x49, 0x6E, 0x76, 0x6F,
      0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00,
      0x05, 0x00, 0x09, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x73, 0x70,
      0x69, 0x72, 0x76, 0x5F, 0x42, 0x75, 0x69, 0x6C, 0x74, 0x49, 0x6E, 0x57,
      0x6F, 0x72, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x49, 0x64, 0x00, 0x00,
      0x47, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
      0x00, 0x40, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
      0x2C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
      0x0D, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
      0x47, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
      0x00, 0x40, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00,
      0x2C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
      0x0E, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
      0x47, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
      0x00, 0x40, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
      0x2C, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
      0x0F, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
      0x47, 0x00, 0x03, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
      0x47, 0x00, 0x0D, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
      0x5F, 0x5F, 0x73, 0x70, 0x69, 0x72, 0x76, 0x5F, 0x42, 0x75, 0x69, 0x6C,
      0x74, 0x49, 0x6E, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x49, 0x6E, 0x76, 0x6F,
      0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x49, 0x64, 0x00, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
      0x0B, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
      0x0C, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x47, 0x00, 0x0B, 0x00,
      0x0C, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x73, 0x70,
      0x69, 0x72, 0x76, 0x5F, 0x42, 0x75, 0x69, 0x6C, 0x74, 0x49, 0x6E, 0x57,
      0x6F, 0x72, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x49, 0x64, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x00, 0x00,
      0x0B, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
      0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x13, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x06, 0x00,
      0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
      0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x15, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
      0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
      0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
      0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
      0x80, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
      0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
      0x09, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x36, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
      0x1F, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00,
      0x11, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
      0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x71, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
      0x12, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00,
      0x14, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
      0x15, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x71, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
      0x15, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
      0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
      0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
      0x17, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x00, 0x05, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
      0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x1A, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
      0x04, 0x00, 0x00, 0x00, 0x46, 0x00, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00,
      0x1B, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
      0x3D, 0x00, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
      0x1B, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
      0x81, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
      0x1A, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x46, 0x00, 0x05, 0x00,
      0x03, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
      0x18, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x05, 0x00, 0x1E, 0x00, 0x00, 0x00,
      0x1D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
      0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00};
  constexpr size_t kAddSpvSize = sizeof(kAddSpv);

  KernelLoaderSpec spec = KernelLoaderSpec::CreateCudaCubinInMemorySpec(
      absl::Span<const uint8_t>(reinterpret_cast<const uint8_t*>(kAddSpv),
                                kAddSpvSize),
      "wrapped_add", 3);

  TF_ASSERT_OK_AND_ASSIGN(std::unique_ptr<Kernel> sycl_kernel,
                          executor->LoadKernel(spec));

  EXPECT_EQ(sycl_kernel->Arity(), 3);
  // TODO(intel-tf): Add check for GetMaxOccupiedBlocksPerCore
}

}  // namespace
}  // namespace stream_executor::gpu
